﻿using System;
using System.Configuration;
using System.Linq;

//á ekki að þurfa lengur?
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using BGCMS.Models;

namespace BGCMS.Controllers
{
    /// <summary>
    /// QuestionController contains all logic connected to questions.
    /// Has different authorization for differenct methods.
    /// </summary>
    public class QuestionController : Controller
    {
        #region Variables

        BGRepository rep = null;

        #endregion Variables

        #region Constructor

        public QuestionController()
        {
            rep = new BGRepository();
        }

        #endregion Constructor

        #region Display methods

        /// <summary>
        /// Displays a list of qestions and links to articles with questions as keywords
        /// </summary>
        /// <returns>Get: /Question</returns>
        public ActionResult Index()
        {
            var questions = from q in rep.GetAllQuestions()
                            where q.IsPublished == true
                            select q;

            // The MenuItem with ID 6 connects to Keywords related to Articles that answer questions
            var keywords = from k in rep.GetKeywords()
                           where k.MenuItemID == 6
                           select k;

            QuestionIndexViewModel model = new QuestionIndexViewModel { Questions = questions, Keywords = keywords };

            return View(model);
        }

        /// <summary>
        /// Displays a particular question and its answer
        /// Only published questions will be accessible
        /// </summary>
        /// <param name="id">The ID of the question</param>
        /// <returns>Get: /Question/Question/[id]</returns>
        public ActionResult Question(int? id)
        {
            if (id.HasValue)
            {
                var model = (from q in rep.GetAllQuestions()
                             where q.ID == id.Value
                             && q.IsPublished == true
                             select q).SingleOrDefault();

                if (model == null)
                {
                    return View("NotFound");
                }

                return View(model);
            }
            return View("NotFound");
        }

        /// <summary>
        /// Displays a list of questions grouped by their status (unanswered/published/unpublished).
        /// Only accessible to Administrator users
        /// </summary>
        /// <returns>Get: /Question/AdminQuestions</returns>
        [Authorize(Roles = "Administrators")]
        public ActionResult AdminQuestions()
        {
            var unanswered = from a in rep.GetAllQuestions()
                             where a.IsAnswered == false
                             select a;

            var unpublished = from b in rep.GetAllQuestions()
                              where b.IsPublished == false
                              && b.IsAnswered == true
                              select b;

            var published = from c in rep.GetAllQuestions()
                            where c.IsPublished == true
                            select c;

            QuestionViewModel model = new QuestionViewModel { Unanswered = unanswered, Unpublished = unpublished, Published = published };

            return View(model);
        }

        #endregion Display methods

        #region Create/Answer(/Edit) methods

        /// <summary>
        /// Displays a form to an authorized user to submit a question.
        /// Only accessible to authorized users.
        /// </summary>
        /// <returns>Get: /Question/CreateQuestion</returns>
        [Authorize]
        public ActionResult CreateQuestion()
        {
            return View(new Question());
        }

        /// <summary>
        /// Submits a question to the database, and is now accessable to Specialists.
        /// A notification is sent to an email configured in the config file.
        /// </summary>
        /// <param name="collection">Form fields filled out by the user</param>
        /// <returns>Get: /Question/MailSuccess</returns>
        [Authorize]
        [HttpPost]
        public ActionResult CreateQuestion(FormCollection collection)
        {
            Question q = new Question();

            MembershipUser user = Membership.GetUser(User.Identity.Name);
            if (user == null)
            {
                return View("UserNotFound");
            }
            q.AskedBy = (Guid)user.ProviderUserKey;

            try
            {
                UpdateModel(q);
                rep.UpdateQuestion(q);
                rep.SaveChanges();
            }
            catch
            {   // On failure to save to database the form is redisplayed
                foreach (var issue in q.QuestionGetRuleViolations())
                {
                    ModelState.AddModelError(issue.QuestionPropertyName, issue.QuestionErrorMessage);
                }
                return View(q);
            }

            // Preconfigured email address that administrators should have access to:
            string recipient = ConfigurationManager.AppSettings["Email"];

            // The Body of the message formed:
            StringBuilder body = new StringBuilder("<h3>");
            body.Append(q.Title);
            body.Append("</h3><p><strong>Fyrirspurn:</strong></p>");
            body.Append(HttpUtility.HtmlDecode(q.Question1));
            body.Append("<p><a href='www.brjostagjof.is'>brjóstagjöf.is</a></p>");

            // The email is sent:
            Email.SendEmail(recipient, "Ný fyrirspurn", body.ToString());

            return View("MailSuccess");
        }

        /// <summary>
        /// Displays a form to answer or edit an answer to an existing question
        /// Only accessible to authorized Specialists
        /// </summary>
        /// <param name="id">The ID of the Question</param>
        /// <returns>Get: /Question/</returns>
        [Authorize(Roles = "Specialists")]
        public ActionResult AnswerQuestion(int? id)
        {
            if (id.HasValue)
            {
                var model = (from q in rep.GetAllQuestions()
                             where q.ID == id.Value
                             select q).SingleOrDefault();

                if (model == null)
                {
                    return View("NotFound");
                }

                return View(model);
            }
            return View("NotFound");
        }

        /// <summary>
        /// Submits an answer to an existing Questions and saves it to the database.
        /// Sends an email with the answer to the user that submitted the question.
        /// </summary>
        /// <param name="id">The ID of the question</param>
        /// <param name="collection">Form fields filled out by the user</param>
        /// <returns>If the user is an Administrator: Get: /Question/AdminQuestions
        /// If the user is a Specialist, but not Administrator: Get: /Specialist/ (index method)</returns>
        [Authorize(Roles = "Specialists")]
        [HttpPost]
        public ActionResult AnswerQuestion(int id, FormCollection collection)
        {
            var result = (from q in rep.GetAllQuestions()
                          where q.ID == id
                          select q).SingleOrDefault();

            MembershipUser user = Membership.GetUser(User.Identity.Name);
            if (user == null)
            {
                return View("UserNotFound");
            }
            result.AnsweredBy = (Guid)user.ProviderUserKey;

            try
            {
                result.IsAnswered = true;
                UpdateModel(result);
                rep.SaveChanges();
            }
            catch
            {   // On failure to save to database the form is redisplayed
                foreach (var issue in result.QuestionGetRuleViolations())
                {
                    ModelState.AddModelError(issue.QuestionPropertyName, issue.QuestionErrorMessage);
                }
                return View(result);
            }

            // Find the email of the user that asked the question
            MembershipUser askedBy = Membership.GetUser(result.AskedBy);
            string recipient = askedBy.Email;

            // The body of the message formed:
            StringBuilder body = new StringBuilder("<h3>Spurt var: ");
            body.Append(result.Title);
            body.Append("</h3>");
            body.Append(HttpUtility.HtmlDecode(result.Question1));
            body.Append("<h3>Svarað af sérfræðingi:</h3>");
            body.Append(HttpUtility.HtmlDecode(result.Answer));
            body.Append("<p>Bestu kveðjur, f.h. <a href='www.brjostagjof.is'>brjóstagjöf.is</a>");

            // The email is sent:
            Email.SendEmail(recipient, "Svar við fyrirspurn", body.ToString());

            // An administrator is redirected to the appropriate administrator page
            if (Roles.IsUserInRole(User.Identity.Name, "Administrators"))
                return RedirectToAction("AdminQuestions");
            return RedirectToAction("Index", "Specialist", null);
        }

        #endregion Create/Answer(/Edit) methods
    }
}